package handler

import (
	"hrms-api/model"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// SalaryRequest 薪资请求结构
type SalaryRequest struct {
	UserID      uint      `json:"user_id" binding:"required"`
	Year        int       `json:"year" binding:"required"`
	Month       int       `json:"month" binding:"required,min=1,max=12"`
	BaseSalary  float64   `json:"base_salary" binding:"required,min=0"`
	Bonus       float64   `json:"bonus" binding:"min=0"`
	Overtime    float64   `json:"overtime" binding:"min=0"`
	Allowance   float64   `json:"allowance" binding:"min=0"`
	Deduction   float64   `json:"deduction" binding:"min=0"`
	Tax         float64   `json:"tax" binding:"min=0"`
	Insurance   float64   `json:"insurance" binding:"min=0"`
	Fund        float64   `json:"fund" binding:"min=0"`
	NetSalary   float64   `json:"net_salary" binding:"required,min=0"`
	PaymentDate time.Time `json:"payment_date"`
	Status      int       `json:"status" binding:"oneof=0 1"`
	Remark      string    `json:"remark" binding:"max=500"`
}

// CreateSalary 创建薪资记录
func CreateSalary(c *gin.Context) {
	var req SalaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		BadRequest(c, err.Error())
		return
	}

	// 检查用户是否存在
	var user model.User
	if err := model.DB.First(&user, req.UserID).Error; err != nil {
		NotFound(c, "User not found")
		return
	}

	// 检查是否已存在该月薪资记录
	var existingSalary model.Salary
	result := model.DB.Where("user_id = ? AND year = ? AND month = ?", req.UserID, req.Year, req.Month).First(&existingSalary)
	if result.Error != gorm.ErrRecordNotFound {
		BadRequest(c, "Salary record already exists for this month")
		return
	}

	// 创建薪资记录
	salary := model.Salary{
		UserID:      req.UserID,
		Year:        req.Year,
		Month:       req.Month,
		BaseSalary:  req.BaseSalary,
		Bonus:       req.Bonus,
		Overtime:    req.Overtime,
		Allowance:   req.Allowance,
		Deduction:   req.Deduction,
		Tax:         req.Tax,
		Insurance:   req.Insurance,
		Fund:        req.Fund,
		NetSalary:   req.NetSalary,
		PaymentDate: req.PaymentDate,
		Status:      req.Status,
		Remark:      req.Remark,
	}

	if err := model.DB.Create(&salary).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, salary)
}

// UpdateSalary 更新薪资记录
func UpdateSalary(c *gin.Context) {
	salaryID := c.Param("id")

	var salary model.Salary
	if err := model.DB.First(&salary, salaryID).Error; err != nil {
		NotFound(c, err.Error())
		return
	}

	var req SalaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		BadRequest(c, err.Error())
		return
	}

	// 更新薪资信息
	updates := map[string]interface{}{
		"base_salary":  req.BaseSalary,
		"bonus":        req.Bonus,
		"overtime":     req.Overtime,
		"allowance":    req.Allowance,
		"deduction":    req.Deduction,
		"tax":          req.Tax,
		"insurance":    req.Insurance,
		"fund":         req.Fund,
		"net_salary":   req.NetSalary,
		"payment_date": req.PaymentDate,
		"status":       req.Status,
		"remark":       req.Remark,
	}

	if err := model.DB.Model(&salary).Updates(updates).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, salary)
}

// GetMySalary 获取个人薪资记录
func GetMySalary(c *gin.Context) {
	// 从上下文中获取当前用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		Unauthorized(c, "User not authenticated")
		return
	}

	// 查询最新的薪资记录
	var salary model.Salary
	result := model.DB.Where("user_id = ?", userID).Order("year DESC, month DESC").First(&salary)
	if result.Error != nil {
		NotFound(c, "No salary record found")
		return
	}

	Success(c, salary)
}

// GetSalaryHistory 获取薪资历史记录
func GetSalaryHistory(c *gin.Context) {
	// 从上下文中获取当前用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		Unauthorized(c, "User not authenticated")
		return
	}

	// 获取查询参数
	startYear := c.Query("start_year")
	startMonth := c.Query("start_month")
	endYear := c.Query("end_year")
	endMonth := c.Query("end_month")

	db := model.DB.Where("user_id = ?", userID)

	// 添加时间范围筛选
	if startYear != "" && startMonth != "" {
		db = db.Where("(year > ? OR (year = ? AND month >= ?))", startYear, startYear, startMonth)
	}
	if endYear != "" && endMonth != "" {
		db = db.Where("(year < ? OR (year = ? AND month <= ?))", endYear, endYear, endMonth)
	}

	// 按时间倒序排序
	db = db.Order("year DESC, month DESC")

	var salaries []model.Salary
	if err := db.Find(&salaries).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, salaries)
}

// CalculateSalary 计算薪资（仅限HR角色）
func CalculateSalary(c *gin.Context) {
	// 检查用户角色
	role, exists := c.Get("role")
	if !exists || role != "admin" {
		Forbidden(c, "Permission denied: admin role required")
		return
	}

	var req SalaryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		BadRequest(c, err.Error())
		return
	}

	// 检查用户是否存在
	var user model.User
	if err := model.DB.First(&user, req.UserID).Error; err != nil {
		NotFound(c, "User not found")
		return
	}

	// 检查是否已存在该月薪资记录
	var existingSalary model.Salary
	result := model.DB.Where("user_id = ? AND year = ? AND month = ?", req.UserID, req.Year, req.Month).First(&existingSalary)
	if result.Error != gorm.ErrRecordNotFound {
		BadRequest(c, "Salary record already exists for this month")
		return
	}

	// 创建薪资记录（状态为未发放）
	salary := model.Salary{
		UserID:      req.UserID,
		Year:        req.Year,
		Month:       req.Month,
		BaseSalary:  req.BaseSalary,
		Bonus:       req.Bonus,
		Overtime:    req.Overtime,
		Allowance:   req.Allowance,
		Deduction:   req.Deduction,
		Tax:         req.Tax,
		Insurance:   req.Insurance,
		Fund:        req.Fund,
		NetSalary:   req.NetSalary,
		PaymentDate: req.PaymentDate,
		Status:      0, // 未发放
		Remark:      req.Remark,
	}

	if err := model.DB.Create(&salary).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, salary)
}

// ConfirmSalary 确认发放薪资（仅限HR角色）
func ConfirmSalary(c *gin.Context) {
	// 检查用户角色
	role, exists := c.Get("role")
	if !exists || role != "admin" {
		Forbidden(c, "Permission denied: admin role required")
		return
	}

	// 获取薪资记录ID
	salaryID := c.Query("salary_id")
	if salaryID == "" {
		BadRequest(c, "Salary ID is required")
		return
	}

	// 查询薪资记录
	var salary model.Salary
	if err := model.DB.First(&salary, salaryID).Error; err != nil {
		NotFound(c, "Salary record not found")
		return
	}

	// 检查薪资状态
	if salary.Status == 1 {
		BadRequest(c, "Salary has already been paid")
		return
	}

	// 更新薪资状态为已发放
	updates := map[string]interface{}{
		"status":       1,
		"payment_date": time.Now(),
	}

	if err := model.DB.Model(&salary).Updates(updates).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, salary)
}

// GetSalary 获取薪资记录
func GetSalary(c *gin.Context) {
	salaryID := c.Param("id")

	var salary model.Salary
	result := model.DB.Preload("User").First(&salary, salaryID)
	if result.Error != nil {
		NotFound(c, result.Error.Error())
		return
	}

	Success(c, salary)
}

// ListSalaries 获取薪资记录列表
func ListSalaries(c *gin.Context) {
	// 检查用户角色
	role, exists := c.Get("role")
	if !exists || role != "hr" {
		Forbidden(c, "Permission denied: HR role required")
		return
	}

	userID := c.Query("user_id")
	year := c.Query("year")
	month := c.Query("month")
	status := c.Query("status")

	db := model.DB.Preload("User")

	// 根据用户ID筛选
	if userID != "" {
		db = db.Where("user_id = ?", userID)
	}

	// 根据年份筛选
	if year != "" {
		db = db.Where("year = ?", year)
	}

	// 根据月份筛选
	if month != "" {
		db = db.Where("month = ?", month)
	}

	// 根据状态筛选
	if status != "" {
		db = db.Where("status = ?", status)
	}

	var salaries []model.Salary
	if err := db.Find(&salaries).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, salaries)
}

// DeleteSalary 删除薪资记录（仅限HR角色）
func DeleteSalary(c *gin.Context) {
	// 检查用户角色
	role, exists := c.Get("role")
	if !exists || role != "admin" {
		Forbidden(c, "Permission denied: admin role required")
		return
	}

	// 获取薪资记录ID
	salaryID := c.Param("id")
	if salaryID == "" {
		BadRequest(c, "Salary ID is required")
		return
	}

	// 查询薪资记录
	var salary model.Salary
	if err := model.DB.First(&salary, salaryID).Error; err != nil {
		NotFound(c, "Salary record not found")
		return
	}

	// 检查薪资状态，已发放的薪资不允许删除
	if salary.Status == 1 {
		BadRequest(c, "Cannot delete salary that has been paid")
		return
	}

	// 删除薪资记录
	if err := model.DB.Delete(&salary).Error; err != nil {
		InternalServerError(c, err.Error())
		return
	}

	Success(c, gin.H{
		"message": "Salary record deleted successfully",
	})
}
